package com.liaozibo.jekyll.config;

import com.liaozibo.jekyll.property.TencentCosProperties;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Configuration
public class TencentCosConfig {
    @Autowired
    private TencentCosProperties tencentCosProperties;

    /**
     * COSClient 是线程安全的类，允许多线程访问同一实例。
     * 因为实例内部维持了一个连接池，创建多个实例可能导致程序资源耗尽，
     * 请确保程序生命周期内实例只有一个，并在不再需要使用时，调用 shutdown 方法将其关闭。
     * 如果需要新建实例，请先将之前的实例关闭。
     * */
    @Bean
    public COSClient cosClient() {
        BasicCOSCredentials credentials = new BasicCOSCredentials(tencentCosProperties.getSecretId(), tencentCosProperties.getSecretKey());
        Region region = new Region(tencentCosProperties.getRegion());
        ClientConfig clientConfig = new ClientConfig(region);
        clientConfig.setHttpProtocol(HttpProtocol.https);
        return new COSClient(credentials, clientConfig);
    }

    /**
     * https://cloud.tencent.com/document/product/436/65935
     * 高级 API 由类 TransferManger 通过封装各个简单接口，来提供更便捷操作的接口。
     * 内部使用一个线程池，来并发接受和处理用户的请求，因此用户也可选择提交多个任务之后异步的执行任务。
     * TransferManager 实例是并发安全的，这里推荐一个进程只创建一个 TransferManager 实例，
     * 当不会再通过这个实例调用高级接口的时候，再选择关闭这个实例。
     */
    @Bean
    public TransferManager transferManager(COSClient cosClient) {
        int nThreads = Runtime.getRuntime().availableProcessors();
        ExecutorService threadPool = Executors.newFixedThreadPool(nThreads, runnable -> {
            Thread thread = new Thread(runnable);
            thread.setDaemon(true); // JekyllUtils 是一个命令行工具 使用 TransferManager 上传文件后，如果使用用户线程，这些线程会阻止进程退出
            return thread;
        });
        return new TransferManager(cosClient, threadPool);
    }

}
